// components/custom-uploader/custom-uploader.ts
import { getUploadOption } from "@/api/index"; // 确保这是你正确的API引入路径

// 为文件对象定义一个更详细的类型
// 我们将明确区分 'url' (用于TDesign组件显示) 和 'path' (原始临时文件路径)
interface CustomFile extends WechatMiniprogram.UploadFile {
  status: "loading" | "done" | "fail";
  percent: number;
  fileID?: string; // 我们业务核心需要的ID，即最终的 fileURL
  uploadTask?: WechatMiniprogram.UploadTask;
}

Component({
  properties: {
    value: {
      type: Array,
      value: [],
    },
    max: {
      type: Number,
      value: 9,
    },
  },

  data: {
    localFileList: [] as CustomFile[],
    gridConfig: {
      column: 4,
      width: 160,
      height: 160,
    },
  },

  observers: {
    value: function (newVal: string[]) {
      if (this.data.localFileList.some((file) => file.status === "loading")) {
        return;
      }
      const innerFileIDs = this.data.localFileList
        .map((f) => f.fileID)
        .filter(Boolean);
      if (JSON.stringify(newVal) !== JSON.stringify(innerFileIDs)) {
        this.setData({
          localFileList: newVal.map(
            (fileID) =>
              ({
                // 对于已存在的文件，url 和 fileID 都是最终的服务器地址
                url: fileID,
                fileID: fileID,
                status: "done",
                percent: 100,
                // 注意：已存在的文件没有本地 path
              } as CustomFile)
          ),
        });
      }
    },
  },

  methods: {
    /**
     * 核心上传逻辑
     * @param file 包含原始临时路径(path)的文件对象
     * @param index 文件在 localFileList 中的索引
     */
    async _startUpload(file: CustomFile, index: number) {
      try {
        // 步骤1: 获取后端上传参数
        const res: any = await getUploadOption();
        // 你的返回体是 res.uploadFileOptions, res.fileURL
        if (!res || !res.uploadFileOptions || !res.fileURL) {
          throw new Error("获取上传参数失败或返回格式不正确");
        }

        const { uploadFileOptions, fileURL } = res;

        // 【优化点】: 先只保存最终的 fileID，不修改用于显示的 url
        // url 此时仍然是本地临时路径，用于给用户预览
        this.setData({
          [`localFileList[${index}].status`]: "loading",
          [`localFileList[${index}].percent`]: 0,
          [`localFileList[${index}].fileID`]: fileURL, // 将最终的URL预先存入 fileID
        });

        // 步骤2: 执行 wx.uploadFile
        const uploadTask = wx.uploadFile({
          url: uploadFileOptions.url,
          filePath: file.url, // 【关键点】: 始终使用原始的本地临时路径(file.path)进行上传
          name: uploadFileOptions.name,
          formData: uploadFileOptions.formData,
          success: (uploadRes) => {
            if (uploadRes.statusCode === 200) {
              // 【关键点】: 上传成功后，才将显示的 url 替换为最终的服务器 URL
              this.setData({
                [`localFileList[${index}].status`]: "done",
                [`localFileList[${index}].percent`]: 100,
                [`localFileList[${index}].url`]: fileURL, // 更新预览图为服务器图片
              });
              this._emitChange(); // 通知父组件更新
            } else {
              throw new Error(`上传失败，状态码：${uploadRes.statusCode}`);
            }
          },
          fail: (err) => {
            console.error("wx.uploadFile 调用失败:", err);
            this.setData({
              [`localFileList[${index}].status`]: "fail",
            });
          },
        });

        // 步骤3: 监听上传进度
        uploadTask.onProgressUpdate((progressRes) => {
          this.setData({
            [`localFileList[${index}].percent`]: progressRes.progress,
          });
        });

        this.setData({
          [`localFileList[${index}].uploadTask`]: uploadTask,
        });
      } catch (error) {
        console.error("上传流程出错:", error);
        this.setData({
          [`localFileList[${index}].status`]: "fail",
        });
      }
    },

    /**
     * t-upload: 用户选择文件后触发
     */
    handleAdd(e: WechatMiniprogram.CustomEvent) {
      const { files } = e.detail;
      const currentFiles = this.data.localFileList;
      // 【关键点】: 创建新的文件对象时，url 和 path 都使用本地临时路径
      const newFiles: CustomFile[] = files.map(
        (file: WechatMiniprogram.UploadFile) => ({
          ...file, // 包含 size 和原始 path
          url: file.url, // url 用于 t-design 组件显示，初始为本地路径
          status: "loading",
          percent: 0,
        })
      );

      this.setData({
        localFileList: [...currentFiles, ...newFiles],
      });

      // 对每个新文件启动上传流程
      newFiles.forEach((file, i) => {
        const indexInList = currentFiles.length + i;
        // 传递新创建的、包含完整信息的 file 对象
        this._startUpload(file, indexInList);
      });
    },

    /**
     * t-upload: 点击删除按钮触发
     */
    handleRemove(e: WechatMiniprogram.CustomEvent) {
      const { index } = e.detail;
      const newList = [...this.data.localFileList];
      newList.splice(index, 1);
      this.setData({
        localFileList: newList,
      });
      this._emitChange();
    },

    /**
     * 自定义方法: 点击重试按钮触发
     */
    handleRetry(e: WechatMiniprogram.CustomEvent) {
      const { index } = e.currentTarget.dataset;
      const fileToRetry = this.data.localFileList[index];

      // 【健壮性优化】: 确保 fileToRetry.path 存在，对于通过 value 初始化的图片，是没有 path 的，不能重试。
      // 不过在当前逻辑下，只有上传失败的本地文件才能点击重试，所以 path 必定存在。
      if (!fileToRetry || !fileToRetry.path) {
        console.error("无法重试：文件没有本地路径。", fileToRetry);
        return;
      }

      this.setData({
        [`localFileList[${index}].status`]: "loading",
        [`localFileList[${index}].percent`]: 0,
      });

      // 【关键点】: 重新调用上传时，传递包含原始 path 的完整文件对象
      this._startUpload(fileToRetry, index);
    },

    /**
     * t-upload: 拖拽排序后触发
     */
    handleDragSort(e: WechatMiniprogram.CustomEvent) {
      const { currentList } = e.detail;
      this.setData({
        localFileList: currentList,
      });
      this._emitChange();
    },

    /**
     * 内部方法: 统一触发 change 事件，向父组件传递最新的 fileID 列表
     */
    _emitChange() {
      // 筛选出所有上传完成的文件，并提取它们的最终 fileID
      const doneFiles = this.data.localFileList
        .filter((file) => file.status === "done" && file.fileID)
        .map((file) => file.fileID as string);
      this.triggerEvent("change", { value: doneFiles });
    },
  },
});
